﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Zatify.WebUI.Areas.Admin.Controllers
{
    using Zatify.WebUI.Infrastructure;
    using Zatify.Domain.Abstract;
    using Zatify.WebUI.Infrastructure.Absrtact;
    using Zatify.WebUI.Admin.Models;
    using Zatify.WebUI.Admin.Helpers;
    using Zatify.Domain.Data;
    using Zatify.WebUI.Infrastructure.Filters;
    using Zatify.WebUI.Models;
    using Zatify.Domain.Entities.Extensions;

    [ZatifyAdminAuthorizeAttribute]
    [Utils.MyRequireHttps]
    public class BusinessController : AdminBaseController
    {
        private const int PageSize = 20;

        private IZatifyRepository repository;

        private const string TempBusinessObject_SessionKey = "TempBusinessObject_SessionKey";
        private BusinessViewModel TempBusinessObject
        {
            get
            {
                return (BusinessViewModel)Session[TempBusinessObject_SessionKey];
            }
            set
            {
                Session[TempBusinessObject_SessionKey] = value;
            }
        }

        private const string TempBusinessCategoriesObject_SessionKey = "TempBusinessCategoriesObject_SessionKey";
        private BusinessCategoriesViewModel TempBusinessCategoriesObject
        {
            get
            {
                return (BusinessCategoriesViewModel)Session[TempBusinessCategoriesObject_SessionKey];
            }
            set
            {
                Session[TempBusinessCategoriesObject_SessionKey] = value;
            }
        }

        protected override AdminModules AdminModule
        {
            get { return AdminModules.Business; }
        }

        public BusinessController(IZatifyRepository repository, IZatifyAuthProvider authProvider)
        {
            this.repository = repository;
        }

        public ActionResult List(string sortOrder, int page = 1, int id = 0)
        {
            double timeZoneOffset = this.User.TimeZoneOffset;

            if (TempBusinessObject != null)
                Session.Remove(TempBusinessObject_SessionKey);

            if (TempBusinessCategoriesObject != null)
                Session.Remove(TempBusinessCategoriesObject_SessionKey);

            var businesses = SortBusinesses(repository.Businesses, sortOrder ?? BusinessSortParameter.RegDateDesc).Skip((page - 1) * PageSize).Take(PageSize).ToList();
            businesses.ForEach(b =>
                {
                    b.DateAdded = b.DateAdded.AddMinutes(-timeZoneOffset);
                });

            var model = new BusinessesListViewModel()
            {
                CurrentUserRole = User.UserRole,

                SelectedBusinessID = id,
                Businesses = businesses,
                PagingInfo = new PagingInfo()
                {
                    TotalItems = repository.Businesses.Count(),
                    ItemsPerPage = PageSize,
                    CurrentPage = page,
                },

                SortOrder = sortOrder,

                BusinessNameSortParam = (sortOrder != BusinessSortParameter.BusinessNameAsc) ?
                                     BusinessSortParameter.BusinessNameAsc : BusinessSortParameter.BusinessNameDesc,

                PromoStatusSortParam = (sortOrder != BusinessSortParameter.PromoStatusAsc) ?
                    BusinessSortParameter.PromoStatusAsc : BusinessSortParameter.PromoStatusDesc,

                UserIDSortParam = (sortOrder != BusinessSortParameter.UserIDAsc) ?
                                BusinessSortParameter.UserIDAsc : BusinessSortParameter.UserIDDesc,

                EmailSortParam = (sortOrder == null || sortOrder == BusinessSortParameter.EmailDesc) ?
                                BusinessSortParameter.EmailAsc : BusinessSortParameter.EmailDesc,

                WebSortParam = (sortOrder != BusinessSortParameter.WebAsc) ?
                                BusinessSortParameter.WebAsc : BusinessSortParameter.WebDesc,

                BusinessPhoneSortParam = (sortOrder != BusinessSortParameter.BusinessPhoneAsc) ?
                                    BusinessSortParameter.BusinessPhoneAsc : BusinessSortParameter.BusinessPhoneDesc,

                CellPhoneSortParam = (sortOrder != BusinessSortParameter.CellPhoneAsc) ?
                                    BusinessSortParameter.CellPhoneAsc : BusinessSortParameter.CellPhoneDesc,

                StatusSortParam = (sortOrder != BusinessSortParameter.StatusAsc) ?
                                    BusinessSortParameter.StatusAsc : BusinessSortParameter.StatusDesc,

                FaxSortParam = (sortOrder != BusinessSortParameter.FaxAsc) ?
                                BusinessSortParameter.FaxAsc : BusinessSortParameter.FaxDesc,

                TollFreeSortParam = (sortOrder != BusinessSortParameter.TollFreeAsc) ?
                                    BusinessSortParameter.TollFreeAsc : BusinessSortParameter.TollFreeDesc,

                RegDateSortParam = (sortOrder != BusinessSortParameter.RegDateAsc) ?
                                    BusinessSortParameter.RegDateAsc : BusinessSortParameter.RegDateDesc
            };

            var pages = new List<SelectListItem>();

            for (int i = 1; i <= model.PagingInfo.TotalPages; i++)
                pages.Add(new SelectListItem() { Text = i.ToString(), Value = i.ToString(), Selected = (i == page) });

            ViewData["pagesCount"] = pages;

            return View(model);
        }

        private IQueryable<Business> SortBusinesses(IQueryable<Business> business, string sortOrder)
        {
            switch (sortOrder)
            {
                case BusinessSortParameter.BusinessNameAsc:
                    return business.OrderBy(b => b.BusinessName);
                case BusinessSortParameter.BusinessNameDesc:
                    return business.OrderByDescending(b => b.BusinessName);

                case BusinessSortParameter.PromoStatusAsc:
                    return business.OrderBy(b => b.PromoStatus);
                case BusinessSortParameter.PromoStatusDesc:
                    return business.OrderByDescending(b => b.PromoStatus);

                case BusinessSortParameter.UserIDAsc:
                    return business.OrderBy(b => b.Login);
                case BusinessSortParameter.UserIDDesc:
                    return business.OrderByDescending(b => b.Login);

                case BusinessSortParameter.EmailAsc:
                    return business.OrderBy(b => b.Email);
                case BusinessSortParameter.EmailDesc:
                    return business.OrderByDescending(b => b.Email);

                case BusinessSortParameter.WebAsc:
                    return business.OrderBy(b => b.Web);
                case BusinessSortParameter.WebDesc:
                    return business.OrderByDescending(b => b.Web);

                case BusinessSortParameter.BusinessPhoneAsc:
                    return business.OrderBy(b => b.BusinessPhone);
                case BusinessSortParameter.BusinessPhoneDesc:
                    return business.OrderByDescending(b => b.BusinessPhone);

                case BusinessSortParameter.CellPhoneAsc:
                    return business.OrderBy(b => b.CellPhone);
                case BusinessSortParameter.CellPhoneDesc:
                    return business.OrderByDescending(b => b.CellPhone);

                case BusinessSortParameter.StatusAsc:
                    return business.OrderBy(b => b.IsActive);
                case BusinessSortParameter.StatusDesc:
                    return business.OrderByDescending(b => b.IsActive);

                case BusinessSortParameter.FaxAsc:
                    return business.OrderBy(b => b.Fax);
                case BusinessSortParameter.FaxDesc:
                    return business.OrderByDescending(b => b.Fax);

                case BusinessSortParameter.TollFreeAsc:
                    return business.OrderBy(b => b.TollFreePhone);
                case BusinessSortParameter.TollFreeDesc:
                    return business.OrderByDescending(b => b.TollFreePhone);

                case BusinessSortParameter.RegDateAsc:
                    return business.OrderBy(b => b.DateAdded);
                case BusinessSortParameter.RegDateDesc:
                    return business.OrderByDescending(b => b.DateAdded);


                default:
                    return business;
            }
        }

        #region 1st Step - GeneralInfo

        [HttpGet]
        public ActionResult GeneralInfo(int? id)
        {
            var model = new BusinessViewModel();

            if (TempBusinessObject != null)
            {
                model = TempBusinessObject;
            }
            else if (id.HasValue && id.Value > 0)
            {
                var business = repository.BusinessGetById(id.Value);

                model.BusinessId = business.BusinessId;
                model.UserId = business.Login;
                model.Password = business.Password;
                model.ConfirmPassword = string.Empty;
                model.BusinessName = business.BusinessName;
                model.Email = business.Email;
                model.Web = business.Web;
                model.BusinessPhone = business.BusinessPhone;
                model.CellPhone = business.CellPhone;
                model.TollFreePhone = business.TollFreePhone;
                model.Fax = business.Fax;
                model.StreetAddress1 = business.StreetAddress1;
                model.StreetAddress2 = business.StreetAddress2;
                model.City = business.City;
                model.StateCode = business.StateCode;
                model.ZipCode = business.ZipCode;
                model.Description = business.Description;
                model.Picture = business.Picture;
                model.PictureContentType = business.PictureContentType;
                model.Longitude = business.Longitude;
                model.Latitude = business.Latitude;

                var businessHours = repository.BusinessGetBusinessHours(id.Value);

                model.SunFrom = businessHours.SunFrom;
                model.SunTo = businessHours.SunTo;
                model.SunClosed = businessHours.SunClosed;
                model.MonFrom = businessHours.MonFrom;
                model.MonTo = businessHours.MonTo;
                model.MonClosed = businessHours.MonClosed;
                model.TueFrom = businessHours.TueFrom;
                model.TueTo = businessHours.TueTo;
                model.TueClosed = businessHours.TueClosed;
                model.WedFrom = businessHours.WedFrom;
                model.WedTo = businessHours.WedTo;
                model.WedClosed = businessHours.WedClosed;
                model.ThuFrom = businessHours.ThuFrom;
                model.ThuTo = businessHours.ThuTo;
                model.ThuClosed = businessHours.ThuClosed;
                model.FriFrom = businessHours.FriFrom;
                model.FriTo = businessHours.FriTo;
                model.FriClosed = businessHours.FriClosed;
                model.SatFrom = businessHours.SatFrom;
                model.SatTo = businessHours.SatTo;
                model.SatClosed = businessHours.SatClosed;

                TempBusinessCategoriesObject = new BusinessCategoriesViewModel();
                TempBusinessCategoriesObject.BusinessId = model.BusinessId.Value;
                TempBusinessCategoriesObject.BusinessName = model.BusinessName;
                TempBusinessCategoriesObject.AllCategories = repository.Categories.ToList();
                TempBusinessCategoriesObject.BusinessCategories = repository.BusinessGetCategories(model.BusinessId.Value).ToList();
                TempBusinessCategoriesObject.TopLevelCategories = TempBusinessCategoriesObject.AllCategories.Where(c => !c.ParentId.HasValue).ToList();


                TempBusinessObject = model;
            }

            PopulateUSStatesViewData(model.StateCode);

            return View(model);
        }

        [HttpPost]
        public ActionResult GeneralInfo(BusinessViewModel model, HttpPostedFileBase image)
        {
            if (ModelState.IsValid)
            {
                model.StreetAddress2 = model.StreetAddress2 ?? String.Empty;
                model.TollFreePhone = model.TollFreePhone ?? String.Empty;
                model.Fax = model.Fax ?? String.Empty;

                if (image != null)
                {
                    model.Picture = new byte[image.ContentLength];
                    model.PictureContentType = image.ContentType;
                    image.InputStream.Read(model.Picture, 0, image.ContentLength);
                }
                else
                {
                    model.Picture = TempBusinessObject != null ? TempBusinessObject.Picture : null;
                    model.PictureContentType = TempBusinessObject != null ? TempBusinessObject.PictureContentType : String.Empty;
                }

                if (TempBusinessObject != null && TempBusinessObject.IsBusinessHoursSpecified)
                {
                    model.IsBusinessHoursSpecified = true;

                    model.SunFrom = TempBusinessObject.SunFrom;
                    model.SunTo = TempBusinessObject.SunTo;
                    model.SunClosed = TempBusinessObject.SunClosed;

                    model.MonFrom = TempBusinessObject.MonFrom;
                    model.MonTo = TempBusinessObject.MonTo;
                    model.MonClosed = TempBusinessObject.MonClosed;

                    model.TueFrom = TempBusinessObject.TueFrom;
                    model.TueTo = TempBusinessObject.TueTo;
                    model.TueClosed = TempBusinessObject.TueClosed;

                    model.WedFrom = TempBusinessObject.WedFrom;
                    model.WedTo = TempBusinessObject.WedTo;
                    model.WedClosed = TempBusinessObject.WedClosed;

                    model.ThuFrom = TempBusinessObject.ThuFrom;
                    model.ThuTo = TempBusinessObject.ThuTo;
                    model.ThuClosed = TempBusinessObject.ThuClosed;

                    model.FriFrom = TempBusinessObject.FriFrom;
                    model.FriTo = TempBusinessObject.FriTo;
                    model.FriClosed = TempBusinessObject.FriClosed;

                    model.SatFrom = TempBusinessObject.SatFrom;
                    model.SatTo = TempBusinessObject.SatTo;
                    model.SatClosed = TempBusinessObject.SatClosed;
                }

                TempBusinessObject = model;

                return RedirectToAction("BusinessHours", new { id = model.BusinessId });
            }

            return View(model);
        }

        public ActionResult GeneralInfoCancel()
        {
            return RedirectToAction("List");
        }

        #endregion

        #region 2nd Step - BusinessHours

        [HttpGet]
        public ActionResult BusinessHours(int? id)
        {
            if (TempBusinessObject == null)
                return RedirectToAction("GeneralInfo", new { id = id });

            var model = new BusinessViewModel();

            if (TempBusinessObject.IsBusinessHoursSpecified)
            {
                model = TempBusinessObject;
            }
            else if (id.HasValue && id > 0)
            {
                var businessHours = repository.BusinessGetBusinessHours(id.Value);

                TempBusinessObject.MonFrom = businessHours.MonFrom;
                TempBusinessObject.MonTo = businessHours.MonTo;
                TempBusinessObject.MonClosed = businessHours.MonClosed;
                TempBusinessObject.Mon24HoursOpen = businessHours.MonIs24Open;

                TempBusinessObject.TueFrom = businessHours.TueFrom;
                TempBusinessObject.TueTo = businessHours.TueTo;
                TempBusinessObject.TueClosed = businessHours.TueClosed;
                TempBusinessObject.Tue24HoursOpen = businessHours.TueIs24Open;

                TempBusinessObject.WedFrom = businessHours.WedFrom;
                TempBusinessObject.WedTo = businessHours.WedTo;
                TempBusinessObject.WedClosed = businessHours.WedClosed;
                TempBusinessObject.Wed24HoursOpen = businessHours.WedIs24Open;

                TempBusinessObject.ThuFrom = businessHours.ThuFrom;
                TempBusinessObject.ThuTo = businessHours.ThuTo;
                TempBusinessObject.ThuClosed = businessHours.ThuClosed;
                TempBusinessObject.Thu24HoursOpen = businessHours.ThuIs24Open;

                TempBusinessObject.FriFrom = businessHours.FriFrom;
                TempBusinessObject.FriTo = businessHours.FriTo;
                TempBusinessObject.FriClosed = businessHours.FriClosed;
                TempBusinessObject.Fri24HoursOpen = businessHours.FriIs24Open;

                TempBusinessObject.SatFrom = businessHours.SatFrom;
                TempBusinessObject.SatTo = businessHours.SatTo;
                TempBusinessObject.SatClosed = businessHours.SatClosed;
                TempBusinessObject.Sat24HoursOpen = businessHours.SatIs24Open;

                TempBusinessObject.SunFrom = businessHours.SunFrom;
                TempBusinessObject.SunTo = businessHours.SunTo;
                TempBusinessObject.SunClosed = businessHours.SunClosed;
                TempBusinessObject.Sun24HoursOpen = businessHours.SunIs24Open;

                model = TempBusinessObject;
            }
            else
            {
                var defaultBussinesHoursFrom = repository.SystemDefaultsGetBusinessHourFrom();
                var defaultBussinesHoursTo = repository.SystemDefaultsGetBusinessHourTo();

                TempBusinessObject.MonFrom = defaultBussinesHoursFrom;
                TempBusinessObject.MonTo = defaultBussinesHoursTo;
                TempBusinessObject.MonClosed = false;
                TempBusinessObject.Mon24HoursOpen = false;

                TempBusinessObject.TueFrom = defaultBussinesHoursFrom;
                TempBusinessObject.TueTo = defaultBussinesHoursTo;
                TempBusinessObject.TueClosed = false;
                TempBusinessObject.Tue24HoursOpen = false;

                TempBusinessObject.WedFrom = defaultBussinesHoursFrom;
                TempBusinessObject.WedTo = defaultBussinesHoursTo;
                TempBusinessObject.WedClosed = false;
                TempBusinessObject.Wed24HoursOpen = false;

                TempBusinessObject.ThuFrom = defaultBussinesHoursFrom;
                TempBusinessObject.ThuTo = defaultBussinesHoursTo;
                TempBusinessObject.ThuClosed = false;
                TempBusinessObject.Thu24HoursOpen = false;

                TempBusinessObject.FriFrom = defaultBussinesHoursFrom;
                TempBusinessObject.FriTo = defaultBussinesHoursTo;
                TempBusinessObject.FriClosed = false;
                TempBusinessObject.Fri24HoursOpen = false;

                TempBusinessObject.SatFrom = defaultBussinesHoursFrom;
                TempBusinessObject.SatTo = defaultBussinesHoursTo;
                TempBusinessObject.SatClosed = false;
                TempBusinessObject.Sat24HoursOpen = false;

                TempBusinessObject.SunFrom = defaultBussinesHoursFrom;
                TempBusinessObject.SunTo = defaultBussinesHoursTo;
                TempBusinessObject.SunClosed = false;
                TempBusinessObject.Sun24HoursOpen = false;

                model = TempBusinessObject;
            }

            PopulateBusinessHoursViewData();

            return View(model);
        }

        [HttpPost]
        public ActionResult BusinessHours(BusinessViewModel model)
        {
            if (TempBusinessObject == null)
                return RedirectToAction("GeneralInfo", new { id = model.BusinessId });

            TempBusinessObject.SunFrom = model.SunFrom;
            TempBusinessObject.SunTo = model.SunTo;
            TempBusinessObject.SunClosed = model.SunClosed;

            TempBusinessObject.MonFrom = model.MonFrom;
            TempBusinessObject.MonTo = model.MonTo;
            TempBusinessObject.MonClosed = model.MonClosed;

            TempBusinessObject.TueFrom = model.TueFrom;
            TempBusinessObject.TueTo = model.TueTo;
            TempBusinessObject.TueClosed = model.TueClosed;

            TempBusinessObject.WedFrom = model.WedFrom;
            TempBusinessObject.WedTo = model.WedTo;
            TempBusinessObject.WedClosed = model.WedClosed;

            TempBusinessObject.ThuFrom = model.ThuFrom;
            TempBusinessObject.ThuTo = model.ThuTo;
            TempBusinessObject.ThuClosed = model.ThuClosed;

            TempBusinessObject.FriFrom = model.FriFrom;
            TempBusinessObject.FriTo = model.FriTo;
            TempBusinessObject.FriClosed = model.FriClosed;

            TempBusinessObject.SatFrom = model.SatFrom;
            TempBusinessObject.SatTo = model.SatTo;
            TempBusinessObject.SatClosed = model.SatClosed;

            TempBusinessObject.IsBusinessHoursSpecified = true;

            return RedirectToAction("BusinessCategories", new { id = model.BusinessId });
        }

        public ActionResult BusinessHoursCancel(int? id)
        {
            return RedirectToAction("GeneralInfo", new { id = id });
        }

        #endregion

        #region 3rd Step - BusinessCategories

        [HttpGet]
        public ActionResult BusinessCategories(int? id)
        {
            if (TempBusinessObject == null)
                return RedirectToAction("GeneralInfo", new { id = id });

            if (TempBusinessCategoriesObject != null)
                return View(TempBusinessCategoriesObject);

            var model = new BusinessCategoriesViewModel()
            {
                BusinessName = TempBusinessObject.BusinessName,
                AllCategories = repository.Categories.ToList(),
                BusinessCategories = new List<Category>()
            };

            model.TopLevelCategories = model.AllCategories.Where(c => !c.ParentId.HasValue).ToList();

            if (id.HasValue && id.Value > 0)
            {
                model.BusinessId = id.Value;
                model.BusinessCategories = repository.BusinessGetCategories(id.Value).ToList();
            }

            TempBusinessCategoriesObject = model;

            return View(TempBusinessCategoriesObject);
        }

        [HttpPost]
        public ActionResult BusinessCategories(BusinessCategoriesViewModel model)
        {
            if (TempBusinessObject == null)
                return RedirectToAction("GeneralInfo", new { id = model.BusinessId });

            if (TempBusinessCategoriesObject == null)
                return RedirectToAction("BusinessCategories", new { id = model.BusinessId });

            return RedirectToAction("PaymentInfo", new { id = model.BusinessId });
        }

        [HttpPost]
        public ActionResult AddBusinessCategories(int? businessId, string categoriesIds)
        {
            if (TempBusinessObject == null)
                return RedirectToAction("GeneralInfo", new { id = businessId });

            if (TempBusinessCategoriesObject == null)
                return RedirectToAction("BusinessCategories", new { id = businessId });

            List<int> catsIds = new List<int>();

            foreach (var id in categoriesIds.Split(','))
                catsIds.Add(Int32.Parse(id));

            var newCats = repository.Categories.Where(c => catsIds.Contains(c.CategoryId)).ToArray();

            foreach (var newCategory in newCats)
            {
                if (!TempBusinessCategoriesObject.BusinessCategories.Any(c => c.CategoryId == newCategory.CategoryId))
                    TempBusinessCategoriesObject.BusinessCategories.Add(newCategory);
            }

            return RedirectToAction("BusinessCategories");
        }

        [HttpPost]
        public ActionResult RemoveBusinessCategories(int? businessId, string removingCategoriesIds)
        {
            if (TempBusinessObject == null)
                return RedirectToAction("GeneralInfo", new { id = businessId });

            if (TempBusinessCategoriesObject == null)
                return RedirectToAction("BusinessCategories", new { id = businessId });

            if (businessId.HasValue && businessId.Value > 0)
                repository.BusinessDeleteCategories(businessId.Value, removingCategoriesIds);

            List<int> catsIds = new List<int>();

            foreach (var id in removingCategoriesIds.Split(','))
                catsIds.Add(Int32.Parse(id));

            var removingCats = repository.Categories.Where(c => catsIds.Contains(c.CategoryId)).ToArray();

            foreach (var cat in removingCats)
            {
                TempBusinessCategoriesObject.BusinessCategories.RemoveAll(c => catsIds.Contains(c.CategoryId));
            }

            return RedirectToAction("BusinessCategories");
        }

        public ActionResult BusinessCategoriesBack(int? id)
        {
            return RedirectToAction("BusinessHours", new { id = id });
        }

        #endregion

        #region 4th Step - PaymentInfo

        [HttpGet]
        public ActionResult PaymentInfo(int? id)
        {
            if (TempBusinessObject == null)
                return RedirectToAction("GeneralInfo", new { id = id });

            var model = new PaymentInfoViewModel();

            if (id.HasValue && id.Value > 0)
            {
                var business = repository.BusinessGetById(id.Value);

                model.BusinessName = TempBusinessObject.BusinessName;

                model.BusinessId = business.BusinessId;
                model.CreditCardNo = business.CreditCardNo;
                model.CreditCardExpDate = business.CreditCardExpDate;
                model.CreditCardName = business.CreditCardName;
                model.CreditCardPin = business.CreditCardPin;
                model.BillingAddress1 = business.BillingAddress1;
                model.BillingAddress2 = business.BillingAddress2;
                model.BillingCity = business.BillingCity;
                model.BillingStateCode = business.BillingStateCode;
                model.BillingZipCode = business.BillingZipCode;
                model.BillingUse = business.BillingUse;
            }

            model.BusinessAddress1 = TempBusinessObject.StreetAddress1;
            model.BusinessAddress2 = TempBusinessObject.StreetAddress2;
            model.BusinessCity = TempBusinessObject.City;
            model.BusinessStateCode = TempBusinessObject.StateCode;
            model.BusinessZipCode = TempBusinessObject.ZipCode;

            PopulateUSStatesViewData(model.BillingStateCode);

            return View(model);
        }

        [HttpPost]
        public ActionResult PaymentInfo(PaymentInfoViewModel model)
        {
            if (TempBusinessObject == null)
                return RedirectToAction("GeneralInfo", new { id = model.BusinessId });

            if (ModelState.IsValid)
            {
                model.BillingAddress2 = model.BillingAddress2 ?? String.Empty;

                var business = new Business()
                {
                    Login = TempBusinessObject.UserId,
                    Email = TempBusinessObject.Email ?? String.Empty,
                    Password = TempBusinessObject.Password,
                    BusinessName = TempBusinessObject.BusinessName,
                    Web = TempBusinessObject.Web ?? String.Empty,
                    BusinessPhone = TempBusinessObject.BusinessPhone ?? String.Empty,
                    CellPhone = TempBusinessObject.CellPhone ?? String.Empty,
                    TollFreePhone = TempBusinessObject.TollFreePhone ?? String.Empty,
                    Fax = TempBusinessObject.Fax ?? String.Empty,
                    StreetAddress1 = TempBusinessObject.StreetAddress1 ?? String.Empty,
                    StreetAddress2 = TempBusinessObject.StreetAddress2 ?? String.Empty,
                    City = TempBusinessObject.City ?? String.Empty,
                    StateCode = TempBusinessObject.StateCode ?? String.Empty,
                    ZipCode = TempBusinessObject.ZipCode ?? String.Empty,
                    Description = TempBusinessObject.Description ?? String.Empty,
                    Latitude = TempBusinessObject.Latitude,
                    Longitude = TempBusinessObject.Longitude,

                    CreditCardNo = model.CreditCardNo ?? String.Empty,
                    CreditCardExpDate = model.CreditCardExpDate ?? (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue,
                    CreditCardName = model.CreditCardName ?? String.Empty,
                    CreditCardPin = model.CreditCardPin ?? String.Empty,
                    BillingAddress1 = (model.BillingUse ? (TempBusinessObject.StreetAddress1 ?? String.Empty) : (model.BillingAddress1 ?? String.Empty)),
                    BillingAddress2 = (model.BillingUse ? (TempBusinessObject.StreetAddress2 ?? String.Empty) : (model.BillingAddress2 ?? String.Empty)),
                    BillingCity = (model.BillingUse ? (TempBusinessObject.City ?? String.Empty) : (model.BillingCity ?? String.Empty)),
                    BillingStateCode = (model.BillingUse ? (TempBusinessObject.StateCode ?? String.Empty) : (model.BillingStateCode ?? String.Empty)),
                    BillingZipCode = (model.BillingUse ? (TempBusinessObject.ZipCode ?? String.Empty) : (model.BillingZipCode ?? String.Empty)),
                    BillingUse = model.BillingUse,

                    Picture = TempBusinessObject.Picture,
                    PictureContentType = TempBusinessObject.PictureContentType
                };

                if (TempBusinessObject.BusinessId.HasValue)
                    business.BusinessId = TempBusinessObject.BusinessId.Value;

                var businessHours = new BusinessHours()
                {
                    SunFrom = TempBusinessObject.SunFrom,
                    SunTo = TempBusinessObject.SunTo,
                    SunClosed = TempBusinessObject.SunClosed,
                    MonFrom = TempBusinessObject.MonFrom,
                    MonTo = TempBusinessObject.MonTo,
                    MonClosed = TempBusinessObject.MonClosed,
                    TueFrom = TempBusinessObject.TueFrom,
                    TueTo = TempBusinessObject.TueTo,
                    TueClosed = TempBusinessObject.TueClosed,
                    WedFrom = TempBusinessObject.WedFrom,
                    WedTo = TempBusinessObject.WedTo,
                    WedClosed = TempBusinessObject.WedClosed,
                    ThuFrom = TempBusinessObject.ThuFrom,
                    ThuTo = TempBusinessObject.ThuTo,
                    ThuClosed = TempBusinessObject.ThuClosed,
                    FriFrom = TempBusinessObject.FriFrom,
                    FriTo = TempBusinessObject.FriTo,
                    FriClosed = TempBusinessObject.FriClosed,
                    SatFrom = TempBusinessObject.SatFrom,
                    SatTo = TempBusinessObject.SatTo,
                    SatClosed = TempBusinessObject.SatClosed
                };

                repository.BusinessUpdate(business, businessHours, TempBusinessCategoriesObject.BusinessCategories);
            }

            return RedirectToAction("List");
        }

        public ActionResult PaymentInfoBack(int? id)
        {
            if (TempBusinessCategoriesObject == null)
                return RedirectToAction("BusinessHours", new { id = id });

            return RedirectToAction("BusinessCategories", new { id = id });
        }

        #endregion

        #region Promotions

        public ActionResult Promotions(int id, int page = 1)
        {
            if (TempBusinessObject == null)
                return RedirectToAction("GeneralInfo", new { id = id });

            if (id > 0)
            {
                var promotions = repository.PromotionsGetList(id).ToList();

                var model = new BusinessPromotionsListViewModel()
                {
                    BusinessId = id,
                    BusinessName = TempBusinessObject.BusinessName,
                    Promotions = promotions.Skip((page - 1) * PageSize).Take(PageSize).ToList(),
                    PagingInfo = new PagingInfo()
                    {
                        TotalItems = promotions.Count(),
                        ItemsPerPage = PageSize,
                        CurrentPage = page,
                    }
                };

                var pages = new List<SelectListItem>();

                for (int i = 1; i <= model.PagingInfo.TotalPages; i++)
                    pages.Add(new SelectListItem() { Text = i.ToString(), Value = i.ToString(), Selected = (i == page) });

                ViewData["pagesCount"] = pages;

                return View(model);
            }
            else
            {
                return RedirectToAction("List");
            }
        }

        [HttpGet]
        public ActionResult Promotion(int businessId, int id)
        {
            if (TempBusinessObject == null)
                return RedirectToAction("GeneralInfo", new { id = businessId });

            if (id > 0)
            {
                var promo = repository.PromotionGetById(id);
                var business = repository.BusinessGetById(promo.BusinessId);

                var model = new BusinessPromotionViewModel();
                model.BusinessId = promo.BusinessId;
                model.BusinessName = business.BusinessName;
                model.Promotion = promo;

                model.PromoSchedulingText = String.Format("{0}",
                    (promo.BaseCostTimingId == PromotionConstants.TIMING_INSTANT_NOW ? "Instant now " + promo.BaseCostTimingScheduledAt.Value :
                    (promo.BaseCostTimingId == PromotionConstants.TIMING_SCHEDULED_AT ? "Scheduled at " + promo.BaseCostTimingScheduledAt.Value.ToString("MM/dd/yy hh:mm tt") :
                    promo.BaseCostTimingId == PromotionConstants.TIMING_ONGOING_WITH_DATE_RANGE ?
                    String.Format("Date range with time interval from {0} to {1}; {2} - {3}",
                                    promo.BaseCostTimingStarts.Value.ToString("MM/dd/yy"),
                                    promo.BaseCostTimingEnds.Value.ToString("MM/dd/yy"),
                                    DateTime.Parse(promo.BaseCostTimingStarts.Value.ToString()).ToString("hh:mm tt"),
                                    DateTime.Parse(promo.BaseCostTimingEnds.Value.ToString()).ToString("hh:mm tt")) : String.Empty)));

                return View(model);
            }

            return RedirectToAction("Promotions", businessId);
        }

        #endregion

        #region Billing

        [HttpGet]
        public ActionResult Billing(int id, DateTime? dateOperation, int page = 1)
        {
            if (id > 0)
            {
                var billingItems = repository.BusinessGetBilling(id, dateOperation).ToList();

                var model = new BusinessBillingListViewModel()
                {
                    BusinessId = id,
                    BusinessName = TempBusinessObject.BusinessName,
                    Billing = billingItems.Skip((page - 1) * PageSize).Take(PageSize).ToList(),
                    PagingInfo = new PagingInfo()
                    {
                        TotalItems = billingItems.Count(),
                        ItemsPerPage = PageSize,
                        CurrentPage = page,
                    }
                };

                return View(model);
            }
            else
                return RedirectToAction("List");
        }

        #endregion

        #region Business actions

        public ActionResult Delete(int id)
        {
            if (id > 0)
                repository.BusinessDeleteById(id);

            return RedirectToAction("List");
        }

        [HttpPost]
        public ActionResult ChangePassword(ChangeBusinessPasswordViewModel model)
        {
            if (ModelState.IsValid)
            {
                repository.BusinessChangePassword(model.BusinessId, model.Password);

                return RedirectToAction("List");
            }
            else
            {
                return Json(false);
            }
        }

        public ActionResult ChangeBusinessStatus(int id, int activate)
        {
            if (activate == 0 || activate == 1)
                repository.BusinessChangeStatus(id, (activate == 1));

            return RedirectToAction("List");
        }

        public ActionResult DeleteBusinesses(int[] businessesIds)
        {
            if (businessesIds != null && businessesIds.Length > 0)
            {
                repository.BusinessesDeleteByIds(businessesIds);
                return Json(new { status = true });
            }
            else
            {
                return Json(new { status = false });
            }
        }

        public ActionResult ChangeBusinessesStatus(int[] businessesIds, int activate)
        {
            if ((businessesIds != null && businessesIds.Length > 0))
            {
                if (activate == 0 || activate == 1)
                    repository.BusinessesChangeStatus(businessesIds, activate == 1);

                return Json(new { status = true });
            }
            else
            {
                return Json(new { status = false });
            }
        }

        #endregion

        #region Helper Methods

        public FileContentResult GetImage(int businessId)
        {
            if (TempBusinessObject != null)
            {
                return File(TempBusinessObject.Picture, TempBusinessObject.PictureContentType);
            }
            else
            {
                var business = repository.BusinessGetById(businessId);

                if (business != null)
                    return File(business.Picture, business.PictureContentType);
                else
                    return null;
            }
        }

        public FileContentResult GetPromotionImage(int promotionId)
        {
            var promotion = repository.PromotionGetById(promotionId);

            if (promotion != null)
                return File(promotion.Picture, promotion.PictureContentType);
            else
                return null;
        }

        public JsonResult BusinessIDUnique(int? businessId, string userId)
        {
            if (businessId.HasValue && businessId.Value > 0)
                return Json(true, JsonRequestBehavior.AllowGet);

            if (!repository.BusinessIsBusinessLoginFree(userId))
                return Json(userId + " is already in use.", JsonRequestBehavior.AllowGet);
            else
                return Json(true, JsonRequestBehavior.AllowGet);
        }

        private void PopulateBusinessHoursViewData()
        {
            ViewData["BusinessHours"] = Helper.GetBusinessHoursSelectList();
        }

        private void PopulateUSStatesViewData(string stateCode)
        {
            ViewData["USStates"] =
                (from state in repository.USStates
                 select new SelectListItem()
                 {
                     Text = state.StateName,
                     Value = state.StateCode,
                     Selected = (!String.IsNullOrEmpty(stateCode) && state.StateCode == stateCode)
                 }).ToList();
        }

        #endregion
    }
}
